
//Copyright 1997-2009 Syrinx Development, Inc.
//This file is part of the Syrinx Web Application Framework (SWAF).
// == BEGIN LICENSE ==
//
// Licensed under the terms of any of the following licenses at your
// choice:
//
//  - GNU General Public License Version 3 or later (the "GPL")
//    http://www.gnu.org/licenses/gpl.html
//
//  - GNU Lesser General Public License Version 3 or later (the "LGPL")
//    http://www.gnu.org/licenses/lgpl.html
//
//  - Mozilla Public License Version 1.1 or later (the "MPL")
//    http://www.mozilla.org/MPL/MPL-1.1.html
//
// == END LICENSE ==
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using System.Xml;

using Swaf;
using Swaf.BizObj;
using Swaf.BizRule;
using Swaf.Container;
using Swaf.Security;

namespace eCom
{
	public class eComPaymentBizRules : Syrinx.BaseBizRules
	{

		public void updateCompanyPaymentTerm(IApplication app, IRuleContext context, Swaf.BGuid.Guid companyId, IBizObj term)
		{
			context.put("companyId", companyId);
			context.put("termId", term.get("id"));
			if (!term.isNew)
				context.RuleGroup.execute(context, "deleteCompanyPaymentTerm", companyId, term.get("id"));

			app.appData.put("DA.eCom.AddCompanyPaymentTerm", context);
		}

		public void deleteCompanyPaymentTerm(IApplication app, IRuleContext context, Swaf.BGuid.Guid companyId, Swaf.BGuid.Guid termId)
		{
			context.put("companyId", companyId);
			context.put("termId", termId);
			app.appData.put("DA.eCom.DeleteCompanyPaymentTerm", context);
		}

		public void updateUserPaymentTerm(IApplication app, IRuleContext context, IBizObj term)
		{
			if (!term.isNew)
				context.RuleGroup.execute(context, "deleteUserPaymentTerm", term.get("userId"), term.get("id"));

			app.appData.put("DA.eCom.AddUserPaymentTerm", term);
		}

		public void deleteUserPaymentTerm(IApplication app, IRuleContext context, Swaf.BGuid.Guid userId, Swaf.BGuid.Guid termId)
		{
			context.put("userId", userId);
			context.put("termId", termId);
			app.appData.put("DA.eCom.DeleteUserPaymentTerm", context);
		}

		public IBizObjList getAllUsersPaymentTerms(IApplication app, IRuleContext context, Swaf.BGuid.Guid companyId)
		{
			context.put("companyId", companyId);
			IBizObjList terms = app.appData.get("DA.eCom.GetAllUsersPaymentTerms", context) as IBizObjList;
			return terms;
		}


		public IBizObjList getUserPaymentTermChoices(IApplication app, IRuleContext context, bool checkCurrentSalesOrder)
		{
			IBizObjList terms = app.bizObjMgr.createList("eComPaymentTerm");
			IBizObj currentSalesOrder = null;
			IResults rc = null;
			string salesOrderPaymentBizObjType = null;

			if (checkCurrentSalesOrder)
			{
				rc = context.RuleGroup.execute(context, "getCurrentSalesOrderDetails");
				if ((currentSalesOrder = rc.CallResults as IBizObj) == null || currentSalesOrder.get("paymentMethod.id") == null)
					checkCurrentSalesOrder = false;
				else
					salesOrderPaymentBizObjType = ((IBizObj)currentSalesOrder.get("paymentMethod")).type.Name;
			}

			object currentUserId = CurrentUser.get("id");
			context.put("currentUserId", currentUserId);
			context.put("anonymousId", ActiveCompany.get("anonymousId"));
			IBizObjList userOptions = app.appData.get("DA.eCom.GetUserPaymentTerms", context) as IBizObjList;
			if (userOptions != null)
			{
				bool hasUserSpecificOptions = false;
				foreach (IBizObj option in userOptions)
				{
					if (option.get("customerId").Equals(currentUserId))
					{
						hasUserSpecificOptions = true;
						break;
					}
				}
				foreach (IBizObj option in userOptions)
					if ((!hasUserSpecificOptions && !option.get("customerId").Equals(currentUserId)) || 
						(hasUserSpecificOptions && option.get("customerId").Equals(currentUserId)))
					{
						IBizObj term = null;
						if (checkCurrentSalesOrder && salesOrderPaymentBizObjType != null && salesOrderPaymentBizObjType.Equals(option.get("bizObjType")))
							term = (IBizObj)currentSalesOrder.get("paymentMethod");
						else
							term = app.bizObjMgr.create(option.get("bizObjType").ToString());
						
						//We have to override the id with the paymentId for the list to always have proper id on the various terms
						//being returned.
						term.put("id", option.get("paymentId"));
						terms.Add(term);
					}
			}

			return terms;
		}

		public IBizObj updateSalesOrderPaymentTermInfo(IApplication app, IRuleContext context,string returnUrl, IBizObj paymentTerm)
		{
			string ruleName = paymentTerm.type.Name;
			ruleName = new StringBuilder(50).Append("update").Append(ruleName).Append("SalesOrderPayment").ToString();
			IBizObj currentSalesOrder = null;
			IResults rc = context.RuleGroup.execute(context, "getCurrentSalesOrderDetails");
			currentSalesOrder = rc.CallResults as IBizObj;
				
			rc = context.RuleGroup.execute(context, ruleName, returnUrl, currentSalesOrder, paymentTerm);
			//TODO: Process payment failures.
			return rc.CallResults as IBizObj;
		}

		public IBizObj updateeComCreditCardPaymentInfoSalesOrderPayment
			(IApplication app, IRuleContext context, string returnUrl, IBizObj salesOrder, IBizObj paymentTerm)
		{
			IBizObj controlInfo = app.bizObjMgr.create("eComPaymentControlInfo");
			DateTime expireDate = (DateTime)paymentTerm.get("expireDate");
			if (expireDate == null || expireDate == DateTime.MinValue)
				paymentTerm.put("expireDate", DateTime.Now.ToUniversalTime().Date);
			context.put("order", salesOrder);
			context.put("payment", paymentTerm);
			app.appData.put("DA.eCom.DeleteSalesOrderPaymentInfo", context);
			app.appData.put("DA.eCom.AddSalesOrderPaymentInfo", context);
			app.appData.put("DA.eCom.UpdateSalesOrderPaymentTermsId", context);

			controlInfo.put("paymentSuccessful", true);
			return controlInfo;
		}

		public IBizObj getSalesOrderPaymentTermDetails(IApplication app, IRuleContext context, object resultValue, object[] inputParams)
		{
			IBizObj salesOrder = resultValue as IBizObj;
			if (salesOrder != null)
			{

				IBizObj termBasics = app.appData.get("DA.eCom.GetPaymentTerm", salesOrder) as IBizObj;
				if (termBasics != null)
				{
					string bizObjType = termBasics.get("bizObjType").ToString();
					string ruleName = new StringBuilder(50).Append("get").Append(bizObjType).Append("PaymentDetails").ToString();

					IResults rc = context.RuleGroup.execute(context, ruleName, salesOrder.get("id"));

					IBizObj termDetails = rc.CallResults as IBizObj;
					if (termDetails != null)
					{
						termDetails.put("id", termBasics.get("paymentId"));
						salesOrder.put("paymentMethod", termDetails);
					}
				}
			}
			return salesOrder;
		}

		public IBizObj geteComCreditCardPaymentInfoPaymentDetails(IApplication app, IRuleContext context, Swaf.BGuid.Guid salesOrderId)
		{
			context.put("id", salesOrderId);
			IBizObj termDetails = app.appData.get("DA.eCom.GetBasicCreditCardPaymentInfo", context) as IBizObj;
			return termDetails;
		}
	}
}
